﻿#pragma once
// Copyright (c) lanyeo 2020-2021
// Licenced under MIT license. See https://opensource.org/licenses/MIT for details.
// code style
// 1. use forward declaration (尽可能使用前置声明)
// 2. include file sequence [other project>c>c++>third>self project]
//
#include <util/fist_list_produce_consume.h>
#include <util/fist-time-inl.h>

#ifdef _MSC_VER
#include <mysql.h>
#else
#include <mysql/mysql.h>
#endif


#include "db_interface.h"

struct DBOperate;

class CDBMariadb : public IDBOperator
{
public:
    explicit CDBMariadb(IDBManager* db_manager);

    virtual ~CDBMariadb();

    int Insert(google::protobuf::Message *data) override;

    cppcoro::task<int> CoInsert(google::protobuf::Message *data) override;

    int Delete(google::protobuf::Message *data) override;

    cppcoro::task<int> CoDelete(google::protobuf::Message *data) override;

    int Delete(const std::string &sql) override;

    cppcoro::task<int> CoDelete(const std::string &sql) override;

    int Update(google::protobuf::Message *data) override;

    cppcoro::task<int> CoUpdate(google::protobuf::Message *data) override;

    int Update(const std::string &sql) override;

    cppcoro::task<int> CoUpdate(const std::string &sql) override;

    int Replace(google::protobuf::Message *data) override;

    cppcoro::task<int> CoReplace(google::protobuf::Message *data) override;

    int Replace(const std::string &sql) override;

    cppcoro::task<int> CoReplace(const std::string &sql) override;

    cppcoro::task<int> Select(const std::string &sql, google::protobuf::Message *what,
                              std::list<google::protobuf::Message *> &results) override;

private:
    int Init() override;

    int TryConnect() override;

    void Tick() override;

    void Destroy() override;

    void ThreadRun();

    void ResetSqlBuilder();
private:
    void set_connected(const bool& is_connected);
    const bool& is_connected() const;
    DBOperate* NewDBOperator();
private:
    IDBManager* m_db_manager;
    bool m_connected;
    MYSQL* m_handle;
    fist::ListProCon<DBOperate*> m_db_op;
    fist::ListProCon<DBOperate*> m_recycle_db_op;
    std::thread m_exec_sql;
    bool m_need_stop;
    fist::ms_t m_last_connect_check;
    std::stringstream m_sql_builder;
};